Skip to content

docs: Guidance for higher-level SDKs to consume MSAL mTLS PoP - #933

Open
Gladwin Johnson (gladjohn) wants to merge 2 commits into
devfrom
gladjohn/sdk-integration-guidance
Open

docs: Guidance for higher-level SDKs to consume MSAL mTLS PoP#933
Gladwin Johnson (gladjohn) wants to merge 2 commits into
devfrom
gladjohn/sdk-integration-guidance

Conversation

@gladjohn

@gladjohn Gladwin Johnson (gladjohn) commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a single documentation file explaining how higher-level SDKs (e.g., azure-identity, azure-sdk-for-python) can integrate with the MSI v2 mTLS Proof-of-Possession API.

This PR contains only documentation — no code changes.

Contents

  • Public API surface and return value contract
  • WindowsCertificate object properties and methods (accurate to implementation)
  • Step-by-step integration pattern (credential → transport)
  • SchannelSession usage (certificate in constructor, not per-request)
  • No-fallback behavior (matches MSAL .NET MtlsPopTokenNotSupportedinImdsV1)
  • End-user experience goal (zero mTLS awareness)
  • .NET comparison table
  • Minimum integration example
  • Future OpenSSL 3 CNG Provider path

Related

Explains how azure-identity and other SDKs can integrate with the
MSI v2 mTLS Proof-of-Possession API.

Covers:
- Public API surface and return value contract
- WindowsCertificate object (accurate property names)
- Step-by-step integration pattern (credential -> transport)
- SchannelSession usage (cert in constructor, not per-request)
- No-fallback behavior matching MSAL .NET
- End-user DX goal (zero mTLS awareness)
- .NET comparison table
- Minimum integration example
- Future OpenSSL 3 CNG Provider path

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@gladjohn
Gladwin Johnson (gladjohn) requested a review from a team as a code owner June 21, 2026 13:49
Copilot AI review requested due to automatic review settings June 21, 2026 13:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new documentation page intended to guide higher-level Azure SDKs in consuming MSAL Python’s Managed Identity v2 mTLS Proof-of-Possession (PoP) integration pattern (credential → transport) and related return-value/typing contracts.

Changes:

  • Introduces a new guidance document describing an mTLS PoP consumption model for higher-level SDKs.
  • Provides sample code for credential integration, auth header construction, and SChannel-based transport usage.
  • Documents intended API contracts (parameters, return keys, and key object types) for the integration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/Guidance-for-Higher-Level-SDKs-to-Consume-MSAL.md
Comment thread docs/Guidance-for-Higher-Level-SDKs-to-Consume-MSAL.md
Comment thread docs/Guidance-for-Higher-Level-SDKs-to-Consume-MSAL.md
Comment thread docs/Guidance-for-Higher-Level-SDKs-to-Consume-MSAL.md
Comment thread docs/Guidance-for-Higher-Level-SDKs-to-Consume-MSAL.md Outdated
Comment thread docs/Guidance-for-Higher-Level-SDKs-to-Consume-MSAL.md
Comment thread docs/Guidance-for-Higher-Level-SDKs-to-Consume-MSAL.md Outdated
Comment thread docs/Guidance-for-Higher-Level-SDKs-to-Consume-MSAL.md
- Add prerequisite note: APIs come from PR #931, not yet on dev
- Note this is standalone docs (not Sphinx-rendered)
- Fix rstrip('/.default') -> removesuffix('/.default')
- Fix AccessToken usage: store token_type on credential (not AccessToken)
- Fix auth policy: read token_type from credential, not token object

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@g2vinay

Copy link
Copy Markdown

From Azure SDK POV:

  1. It won't be a clean/smooth integration into python azure-core via the SChannel transport (involves native bindings), as it will involve building an adapter around it for windows only AKV scenario here. Whether the current python http stack works with SChannel Transport or not, is something to be confirmed by the Identity Python SDK owner.

  2. The distribution of native Attestation Lib (5.3 MB), will add additional bloat for 3P.

  3. Majority Python customers are linux focused. Windows is minority. There won't be major demand for the windows flow.


## Future: OpenSSL 3 CNG Provider (Strategic Path)

When a Microsoft-supported OpenSSL 3 CNG Provider becomes available, the

@kashifkhan Kashif Khan (kashifkhan) Aug 7, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to flag that this "strategic path," as written, isn't reachable today and likely not for a long while. I checked with the Python core devs on whether hardware-key mTLS would become reachable from the stdlib ssl  module /  SSLContext , and the answer was "not coming any time soon."

As y'all know, ssl.SSLContext has no way to reference a provider/PKCS#11 key, load_cert_chain  only accepts key material as files, and there's no signing-callback or provider-key hook. So even if a Microsoft-supported OpenSSL 3 CNG provider existed, requests/aiohttp  still couldn't use it, because both sit on stdlib ssl, which can't point at a provider-backed key by thumbprint.

The snippet in this section ( create_mtls_context(thumbprint=...)  → plain  requests.get(...) ) would require exactly the CPython feature that doesn't exist.

The proper channel for this is a new TLS module (the PEP 543 /  tlslib  effort), and its native-backend work (incl. SChannel) is currently stalled for lack of contributors https://discuss.python.org/t/pre-pep-discussion-revival-of-pep-543-a-unified-tls-api-for-python/51263

They are looking for people who can drive this however :)

```python
from azure.core.pipeline.transport import HttpTransport

class SchannelTransport(HttpTransport):

@kashifkhan Kashif Khan (kashifkhan) Aug 7, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This particular Schannel Transport will basically have to mirror the functionality provided by requests and aiohttp ( for async ) . You will have to create a full WinHTTP based HTTP Client making sure we get the following features out from it :

  • request/response serialization and a conformant  azure.core.rest.HttpResponse  (streaming/ iter_bytes / read /encoding) -> for folks who are using storage, cosmos, etc etc that have different needs from a http client
  • connection pooling / keep-alive (the sketch opens a fresh mTLS handshake per request)
  • redirects, proxies, timeouts, retries, TLS config, and error→exception mapping — all of which WinHTTP does differently than requests/aiohttp, so they'd have to be reconciled to keep behavior consistent across platforms
  • a separate async transport entirely, since  aiohttp  can't present the key and WinHTTP here is sync

A few thoughts on differences -

  • does the transport need to worry about differences between Windows versions for eg
  • does winhttp support reading certs in the same manner as requests/aiohttp ?
  • Will standard proxy env vars ( HTTP_PROXY / HTTPS_PROXY / NO_PROXY ) be honored
  • Diagnostics diverge too:  urllib3 / aiohttp  debug logging (and standard support steps) won't work on WinHTTP — its tracing lives in Windows ETW — and policy-level logs may not reflect WinHTTP's internal redirects/headers.

Just this itself greatly increases the effort and maintenance cost and the security concerns around this too

credential = ManagedIdentityCredential(mtls_pop=True)

# Standard SDK usage — no mTLS awareness needed by the developer
client = SecretClient(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

credential and transport are separate in azure-core. So doesn't SecretClient still need updating to hand the credential to a WinHTTP transport and use it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants